#include "bthread_task.h"
#include <cppbase/utility.h>
#include <filestore/bar_file.h>
void ReadBarTask::run()
{
    brpc::ClosureGuard done_guard(done);

    int exch = int(request->exchange_id());
    auto symbol = request->symbol();
    int start_date = request->start_date();
    std::unique_ptr<char[]> res;
    auto bs = request->barsize();
    BarFile bfile(::Exchange(exch), symbol, BarSize(bs));
    int barcnt, rowsize; //how many days,bytes per day
    if (start_date != 0)
    {
        res = bfile.get_bar(start_date, request->end_date(), &barcnt, &rowsize);
    }
    else
    {
        int rbegin = request->rbegin();
        barcnt = request->count();
        res = bfile.get_bar(rbegin, &barcnt, &rowsize);

    } // user should free memory in res!!!!
    cntl->response_attachment().append_user_data((void *)res.release(), barcnt * rowsize, [](void *p)
                                                 {delete[] (char*)p; });
}
bool bar_validator(Bar& b ){
    if(b.time<943891200 || b.time>1890662400)// must between 2000,2030
        return false;
    
    return true;

}
void UpdateBarTask::run()
{
    brpc::ClosureGuard done_guard(done);
    int exch = request->exchange_id();
    std::string symbol = request->symbol();
    BarSize bs = BarSize(request->barsize());
    int rowsize = request->rowsize();
    int rowcount = request->rowcount();
    BarFile bfile(::Exchange(exch), symbol, BarSize(bs));
    auto buf = cntl->request_attachment();
    int savecnt;
    if (bs == BarSize::Day1)
    {   LOG(INFO)<<"will update daybar";
        auto bset = bfile.make_barset();
        for (int i = 0; i < rowcount; i++)
        {
            Bar oneday;
            buf.cutn((char *)&oneday, rowsize);
            if(!bar_validator(oneday)){
                cntl->SetFailed(brpc::HTTP_STATUS_NOT_IMPLEMENTED, "%s", "invalid bar data");
                return;
            }
            bset.emplace(oneday);
        }
        
       savecnt= bfile.update_daybar(bset);

    }
    else if (bs == BarSize::Min1)
    {LOG(INFO)<<"will update min daybar";
        auto bmap = bfile.make_min_barmap();

        for (int i = 0; i < rowcount; i++)
        {

            uint32_t t;
            buf.cutn(&t, 4);
            bmap[t].resize((rowsize - sizeof(uint32_t)) / sizeof(MinuteBar));
            buf.cutn((char *)bmap[t].data(), rowsize - sizeof(uint32_t));
        }
       savecnt= bfile.update_minbar(bmap);
    }
    else
    {
        cntl->SetFailed(brpc::HTTP_STATUS_NOT_IMPLEMENTED, "%s", "no handler");
    }
    response->add_arg_int32(savecnt);
}

void ReadBarRangeTask::run()
{
    brpc::ClosureGuard done_guard(done);
    int exch = int(request->exchange_id());
    auto symbol = request->symbol();
    auto bs = request->barsize();
    BarFile bfile(::Exchange(exch), std::move(symbol), BarSize(bs));
    auto res = bfile.get_time_range();
    if (res.first == 0 && res.first == res.second ) {
        cntl->SetFailed(brpc::HTTP_STATUS_NOT_FOUND,"bar file not found");
    }
    else {
        response->add_arg_int32(res.first);
        response->add_arg_int32(res.second);
    }
    

}
